using Microsoft.Win32.SafeHandles;

using System;
using System.Security;
using System.Security.Permissions;
using System.Runtime.ConstrainedExecution;
using System.Runtime.InteropServices;


namespace Agron.Services.Broadcasting
{
    /// <summary>
    /// A <see cref="SafeHandle"/> implementation for a <c>Windows Hook Handle</c>.
    /// </summary>
    [SecurityPermission(SecurityAction.LinkDemand, UnmanagedCode = true)]
    internal class SafeMouseHookHandle : SafeHandleMinusOneIsInvalid
    {
        /// <summary>
        /// Initializes a new instance of the <see cref="SafeMouseHookHandle"/> class.
        /// </summary>
        private SafeMouseHookHandle() : base(true) { }

        /// <summary>
        /// When overridden in a derived class, executes the code required to free the handle.
        /// </summary>
        /// <returns>
        /// true if the handle is released successfully; otherwise, in the event of a catastrophic failure, false. In this case, it generates a ReleaseHandleFailed Managed Debugging Assistant.
        /// </returns>
        protected override bool ReleaseHandle()
        {
            return NativeMethods.UnhookWindowsHookEx(handle);
        }

        static class NativeMethods
        {
            /// <summary>The UnhookWindowsHookEx function removes a hook procedure installed in a hook chain by the SetWindowsHookEx function.</summary>
            /// <param name="hhk">Handle to the hook procedure</param>
            /// <returns>true on success; otherwise, false.</returns>
            [SuppressUnmanagedCodeSecurity]
            [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
            [DllImport("user32.dll", SetLastError = true)]
            [return: MarshalAs(UnmanagedType.Bool)]
            internal static extern bool UnhookWindowsHookEx(IntPtr hhk);
        }
    }
}
